package com.erp.erp_ui.business.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.erp.enums.ModuleTypeEnum;
import com.erp.enums.OperationStatusEnum;
import com.erp.enums.OperationTypeEnum;
import com.erp.erp_entitys.business.entity.*;
import com.erp.erp_entitys.business.req.*;
import com.erp.erp_entitys.business.rsp.ImportTaskProductPartsRsp;
import com.erp.erp_entitys.business.rsp.ImportTaskProductRsp;
import com.erp.erp_entitys.business.rsp.QueryTaskStatisticsOneRes;
import com.erp.erp_entitys.business.rsp.QueryTaskStatisticsTwoRes;
import com.erp.erp_entitys.log.entity.DataInfoLogEntity;
import com.erp.erp_entitys.warehouse.entity.AnnexEntity;
import com.erp.erp_entitys.warehouse.entity.TempAnnexEntity;
import com.erp.erp_servers.ShipmentPlan.IShipmentPlanService;
import com.erp.erp_servers.business.*;
import com.erp.erp_servers.log.IDataInfoLogService;
import com.erp.erp_servers.warehouse.IAnnexService;
import com.erp.erp_servers.warehouse.ITempAnnexService;
import com.erp.erp_ui.business.req.*;
import com.erp.erp_ui.business.vo.*;
import com.erp.erp_ui.money.req.OperationReq;
import com.erp.erp_ui.warehouse.enums.DataIsValidEnum;
import com.erp.erp_ui.warehouse.req.AnnexReq;
import com.erp.erp_ui.warehouse.vo.AnnexVo;
import com.erp.utils.*;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName : TaskService
 * @Description : 出口业务-任务业务逻辑层
 * @Author : lst
 * @Date: 2021-01-18 02:37
 */
@Service
public class TaskService {

    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(TaskService.class);

    /**
     * 任务主表接口
     */
    private final ITaskService taskService;

    /**
     * 任务产品明细接口
     */
    private final ITaskProductService taskProductService;

    /**
     * 任务配件接口
     */
    private final ITaskProductPartsService taskProductPartsService;

    /**
     * 任务费用接口
     */
    private final ITaskCostService taskCostService;

    /**
     * 附件接口
     */
    private final IAnnexService annexService;

    /**
     * 临时附件接口
     */
    private final ITempAnnexService tempAnnexService;

    /**
     * 出运计划接口
     */
    private final IShipmentPlanService shipmentPlanService;

    /**
     * 外销产品接口
     */
    private final IExportContractProductService exportContractProductService;

    /**
     * 操作日志信息接口
     */
    private final IDataInfoLogService dataInfoLogService;

    @Autowired
    public TaskService(ITaskService taskService,
                       ITaskProductService taskProductService,
                       ITaskProductPartsService taskProductPartsService,
                       ITaskCostService taskCostService,
                       IAnnexService annexService,
                       ITempAnnexService tempAnnexService,
                       IShipmentPlanService shipmentPlanService,
                       IExportContractProductService exportContractProductService,
                       IDataInfoLogService dataInfoLogService) {
        this.taskService = taskService;
        this.taskProductService = taskProductService;
        this.taskProductPartsService = taskProductPartsService;
        this.taskCostService = taskCostService;
        this.annexService = annexService;
        this.tempAnnexService = tempAnnexService;
        this.shipmentPlanService = shipmentPlanService;
        this.exportContractProductService = exportContractProductService;
        this.dataInfoLogService = dataInfoLogService;
    }

    /**
     * 新增、修改
     * @param req 新增、修改入参
     * @param creator 创建人
     * @param createNo 创建人编码
     * @return 新增、修改结果
     */
    @Transactional(rollbackFor = Exception.class)
    public R add(AddTaskReq req, String creator, String createNo) throws ParseException {
        //一：单号唯一性校验
        boolean billNoCheckFlag = (null != req.getId() && req.getBillNo().equals(req.getNewBillNo()));
        if(!billNoCheckFlag){
            //单号做唯一校验
            boolean billNoFlag = checkRepeatBillNo(req.getBillNo());
            if(!billNoFlag){
                return R.buildError(ResultStatusEnum.BILL_NO_REPEAT);
            }
        }

        //二：主表新增
        Integer id = insert(req, creator, createNo);
        if(id == null){
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }

        //三：明细新增及对应配件
        insertDetail(req, id, creator, createNo);

        //四：费用新增
        addCost(req, id, creator, createNo);

        //五：添加附件信息
        boolean flag = addAnnex(req, id, creator, createNo);
        if(!flag){
            LOGGER.info("出口业务-外销-批量新增附件异常");
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        //删除临时附件信息
        deleteTempAnnex(req.getAnnexList());
        return R.build(ResultStatusEnum.SUCCESS);
    }

    /**
     * 批量处理临时附件信息，将临时附件设置为失效
     * @param annexReqs
     */
    private void deleteTempAnnex(List<AnnexReq> annexReqs){
        //没有附件
        if(CollectionUtils.isEmpty(annexReqs)){
            return;
        }
        //存在附件
        for(AnnexReq annex : annexReqs){
            if(null != annex.getNews()){
                //旧附件,不用修改
                continue;
            }
            TempAnnexEntity tempAnnex = new TempAnnexEntity();
            //设置临时附件id
            tempAnnex.setId(annex.getId());
            //设置修改时间
            tempAnnex.setUpdateTime(new Date());
            //将附件设置为失效
            tempAnnex.setValid(DataIsValidEnum.INVALID.getId());
            tempAnnexService.update(tempAnnex);
        }

    }

    /**
     * 附件新增
     * @param req 入参信息
     * @param id 主表id
     * @param operator 操作人
     * @param operatorNo 操作人编码
     * @return 是否新增成功(true:成功 false:失败 )
     */
    private boolean addAnnex(AddTaskReq req, Integer id, String operator, String operatorNo) {
        try {
            List<AnnexReq> annexReqs = req.getAnnexList();
            //没有附件,将该id关联的所有附件设为无效
            if(CollectionUtils.isEmpty(annexReqs)){
                AnnexEntity annexReq = new AnnexEntity();
                annexReq.setParentId(id);
                annexReq.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
                List<AnnexEntity> annexList = annexService.queryAll(annexReq);
                if(!CollectionUtils.isEmpty(annexList)){
                    for(AnnexEntity annex : annexList){
                        AnnexEntity updateAnnex= new AnnexEntity();
                        updateAnnex.setId(annex.getId());
                        //将被删除的附件设为失效
                        updateAnnex.setValid(DataIsValidEnum.INVALID.getId());
                        annexService.update(updateAnnex);
                    }
                }
                return true;
            }
            //存在附件,新增附件信息
            List<AnnexEntity> list = new ArrayList<>();
            for(AnnexReq annexReq : annexReqs){
                if(null != annexReq.getNews()){
                    //属于旧附件 不新增
                    continue;
                }
                AnnexEntity annex = new AnnexEntity();
                BeanUtils.copyProperties(annexReq, annex);
                //设置关联模块id
                annex.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
                //设置关联模块父id
                annex.setParentId(id);
                //设置上传时间
                annex.setUploadTime(DateUtils.convertStringToDate(annexReq.getUploadTime(), DateUtils.DATE_PATTERN));
                //设置修改时间
                annex.setUpdateTime(new Date());
                //设置操作人
                annex.setOperator(operator);
                //设置操作人编码
                annex.setOperatorNo(operatorNo);
                //设置数据有效
                annex.setValid(1);

                list.add(annex);
            }
            if(!CollectionUtils.isEmpty(list)){
                //附件批量新增
                annexService.batchInsert(list);
            }
            //获取删除的附件
            List<Integer> deleteAnnexIds = req.getDeleteAnnexIds();
            if(deleteAnnexIds.size() > 0){
                //存在被删除的旧附件，数据库删除
                for(Integer deleteAnnexId : deleteAnnexIds){
                    AnnexEntity annexEntity = new AnnexEntity();
                    //附件主键ID
                    annexEntity.setId(deleteAnnexId);
                    //将被删除的附件设为失效
                    annexEntity.setValid(DataIsValidEnum.INVALID.getId());
                    //删除时间
                    annexEntity.setUpdateTime(new Date());

                    annexService.update(annexEntity);
                }
            }

            return true;
        }catch (Exception e){
            throw new RuntimeException();
        }
    }

    /**
     * 费用新增
     * @param req 新增参数
     * @param id 主表id
     */
    private void addCost(AddTaskReq req, Integer id, String creator, String createNo){
        if(CollectionUtils.isEmpty(req.getCostList())){
            return;
        }
        List<TaskCostEntity> addCostList = new ArrayList<>();
        //费用id
        List<Integer> newIds = new ArrayList<>();
        for(AddTaskCostReq cost : req.getCostList()){
            TaskCostEntity updateReq = new TaskCostEntity();
            //赋值
            BeanUtils.copyProperties(cost, updateReq);

            if(null == cost.getId()){
                //新增

                //新增日志信息
                DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
                //模块主表id
                dataInfoLog.setParentId(id);
                //模块id
                dataInfoLog.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
                //操作人编码
                dataInfoLog.setOperationCode(createNo);
                //操作人名称
                dataInfoLog.setOperationName(creator);
                //操作时间
                dataInfoLog.setOperationTime(new Date());
                //操作类型
                dataInfoLog.setOperationType(OperationTypeEnum.INSERT_DATA.getId());
                //操作内容
                dataInfoLog.setOperationContent("费用信息:");

                dataInfoLogService.insert(dataInfoLog);

                //父id
                updateReq.setParentId(id);
                //创建时间
                updateReq.setCreateDate(new Date());
                //设为有效
                updateReq.setValid(DataIsValidEnum.VALID.getId());

                addCostList.add(updateReq);
            }else {
                //修改

                TaskCostEntity costData = taskCostService.queryById(cost.getId());
                BeanChangeLogUtil logUtil = new BeanChangeLogUtil();
                String info = logUtil.contrastObj(costData, updateReq);
                if(StringUtils.isNotEmpty(info)){
                    //新增日志信息
                    DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
                    //模块主表id
                    dataInfoLog.setParentId(id);
                    //模块id
                    dataInfoLog.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
                    //操作人编码
                    dataInfoLog.setOperationCode(createNo);
                    //操作人名称
                    dataInfoLog.setOperationName(creator);
                    //操作时间
                    dataInfoLog.setOperationTime(new Date());
                    //操作类型
                    //操作内容
                    dataInfoLog.setOperationContent("费用信息:" + info);
                    //操作类型
                    dataInfoLog.setOperationType(OperationTypeEnum.UPDATE_DATA.getId());

                    dataInfoLogService.insert(dataInfoLog);
                }

                //修改时间
                updateReq.setModifyTime(new Date());
                taskCostService.update(updateReq);
                newIds.add(updateReq.getId());
            }
        }
        //处理被删除的费用
        handleBeenDeletedCost(id, newIds);

        if(!CollectionUtils.isEmpty(addCostList)){
            //费用批量新增
            taskCostService.addList(addCostList);
        }
    }

    /**
     * 处理被删除的费用
     * @param id 报价id
     * @param newIds 费用id
     */
    private void handleBeenDeletedCost(int id, List<Integer> newIds){
        //修改-找出被删除的费用

        TaskCostEntity costReq = new TaskCostEntity();
        //设置报价id
        costReq.setParentId(id);
        //查询有效数据
        costReq.setValid(DataIsValidEnum.VALID.getId());
        //调用接口查询结果
        List<TaskCostEntity> costList = taskCostService.queryAll(costReq);
        if(!CollectionUtils.isEmpty(costList)){
            //获取id集合
            List<Integer> oldIds = costList.stream().map(p -> p.getId()).collect(Collectors.toList());
            //找出被删除的id
            Collection collection = new ArrayList(oldIds);
            collection.removeAll(newIds);
            if(collection.size() > 0){
                //遍历被删除的费用
                Iterator<Integer> ids = collection.iterator();
                while (ids.hasNext()){
                    int costId = ids.next();
                    TaskCostEntity updateReq = new TaskCostEntity();
                    //修改主键
                    updateReq.setId(costId);
                    //修改时间
                    updateReq.setModifyTime(new Date());
                    //设为无效
                    updateReq.setValid(DataIsValidEnum.INVALID.getId());

                    taskCostService.update(updateReq);
                }
            }
        }
    }

    /**
     * 明细新增
     * @param req 新增对象
     * @param id 主表id
     */
    public void insertDetail(AddTaskReq req, int id, String creator, String createNo) throws ParseException {
        if(!CollectionUtils.isEmpty(req.getDetailList())){
            //获取明细id集合
            List<Integer> newIds = new ArrayList<>();
            for(AddTaskProductReq detailReq : req.getDetailList()){
                //初始化明细对象
                TaskProductEntity detail = new TaskProductEntity();
                //赋值
                BeanUtils.copyProperties(detailReq, detail);
                //交货期日期转换
                detail.setDeliveryDate(DateUtils.convertStringToDate(detailReq.getDeliveryDate(), DateUtils.DATE_PATTERN));
                //设置主表id
                detail.setParentId(id);
                //设置数据有效性(0:无效 1:有效)
                detail.setValid(DataIsValidEnum.VALID.getId());
                if(null == detailReq.getId()){
                    if (req.getId() != null) {
                        //表明修改新增产品
                        //新增日志信息
                        DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
                        //模块主表id
                        dataInfoLog.setParentId(id);
                        //模块id
                        dataInfoLog.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
                        //操作人编码
                        dataInfoLog.setOperationCode(createNo);
                        //操作人名称
                        dataInfoLog.setOperationName(creator);
                        //操作类型
                        dataInfoLog.setOperationType(OperationTypeEnum.INSERT_DATA.getId());
                        //操作时间
                        dataInfoLog.setOperationTime(new Date());
                        //操作内容
                        dataInfoLog.setOperationContent("产品信息:" + "产品编码:" + detail.getProductCode() + ",规格编码:" + detail.getSpecificationCode());

                        dataInfoLogService.insert(dataInfoLog);
                    }

                    //剩余数量默认等于入库数量
                    detail.setProductSurplusNum(detailReq.getProductNum());
                    //新增
                    taskProductService.insert(detail);
                    //获取明细id
                    Integer detailId = detail.getId();
                    newIds.add(detailId);
                    //配件新增
                    if(!CollectionUtils.isEmpty(detailReq.getPartsList())){
                        //初始化配件对象集合
                        List<TaskProductPartsEntity> partsList = new ArrayList<>();
                        for(AddTaskProductPartsReq parts : detailReq.getPartsList()){
                            //初始化配件对象
                            TaskProductPartsEntity partsEntity = new TaskProductPartsEntity();
                            //赋值
                            BeanUtils.copyProperties(parts, partsEntity);
                            //报价id
                            partsEntity.setParentId(id);
                            //产品明细id
                            partsEntity.setDetailId(detailId);
                            //创建时间
                            partsEntity.setCreateDate(new Date());
                            //设置数据有效性(0:无效 1:有效)
                            partsEntity.setValid(DataIsValidEnum.VALID.getId());

                            partsList.add(partsEntity);
                        }
                        if(!CollectionUtils.isEmpty(partsList)){
                            //新增配件
                            taskProductPartsService.addList(partsList);
                        }

                    }
                }else {
                    //修改

                    //添加修改日志
                    //获取修改前对象数据
                    TaskProductEntity oldData = taskProductService.queryById(detailReq.getId());
                    BeanChangeLogUtil logUtil = new BeanChangeLogUtil();
                    String info = logUtil.contrastObj(oldData, detail);
                    if(StringUtils.isNotEmpty(info)){
                        //新增日志信息
                        DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
                        //模块主表id
                        dataInfoLog.setParentId(id);
                        //模块id
                        dataInfoLog.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
                        //操作人编码
                        dataInfoLog.setOperationCode(createNo);
                        //操作人名称
                        dataInfoLog.setOperationName(creator);
                        //操作类型
                        dataInfoLog.setOperationType(OperationTypeEnum.UPDATE_DATA.getId());
                        //操作时间
                        dataInfoLog.setOperationTime(new Date());
                        //操作内容
                        dataInfoLog.setOperationContent("产品信息:" + info);

                        dataInfoLogService.insert(dataInfoLog);
                    }

                    //获取明细id
                    newIds.add(detailReq.getId());
                    //明细修改
                    taskProductService.update(detail);
                    //配件修改
                    if(!CollectionUtils.isEmpty(detailReq.getPartsList())){
                        List<Integer> newPartsIds = new ArrayList<>();
                        for(AddTaskProductPartsReq parts : detailReq.getPartsList()){
                            if(null == parts.getId()){
                                //新增
                                //初始化配件对象
                                TaskProductPartsEntity partsEntity = new TaskProductPartsEntity();
                                //赋值
                                BeanUtils.copyProperties(parts, partsEntity);
                                //报价id
                                partsEntity.setParentId(id);
                                //产品明细id
                                partsEntity.setDetailId(detailReq.getId());
                                //创建时间
                                partsEntity.setCreateDate(new Date());
                                //设置数据有效性(0:无效 1:有效)
                                partsEntity.setValid(DataIsValidEnum.VALID.getId());

                                taskProductPartsService.insert(partsEntity);
                                //获取配件id
                                newPartsIds.add(partsEntity.getId());
                            }else {
                                //修改
                                if(detailReq.getId().equals(parts.getDetailId())){
                                    //获取配件id
                                    newPartsIds.add(parts.getId());
                                    //初始化配件对象
                                    TaskProductPartsEntity partsEntity = new TaskProductPartsEntity();
                                    //赋值
                                    BeanUtils.copyProperties(parts, partsEntity);
                                    //修改时间
                                    partsEntity.setModifyTime(new Date());

                                    taskProductPartsService.update(partsEntity);
                                }
                            }

                        }
                        //处理被删除的配件
                        handleBeenDeletedParts(detailReq.getId(), newPartsIds);
                    }
                }

            }

            //处理被删除的明细
            handleBeenDeletedDetail(req, id, newIds, creator, createNo);

        }
    }

    /**
     * 处理被删除的明细
     * @param req 明细
     * @param id 主表id
     * @param newIds 修改后未被删除的细id集合
     */
    private void handleBeenDeletedDetail(AddTaskReq req, int id, List<Integer> newIds, String creator, String createNo){
        if(null != req.getId()){
            //修改-找出被删除的明细

            TaskProductEntity detailReq = new TaskProductEntity();
            //设置付款id
            detailReq.setParentId(id);
            //查询有效数据
            detailReq.setValid(DataIsValidEnum.VALID.getId());
            //调用接口查询结果
            List<TaskProductEntity> detailList = taskProductService.queryAll(detailReq);
            if(!CollectionUtils.isEmpty(detailList)){
                //获取id集合
                List<Integer> oldIds = detailList.stream().map(p -> p.getId()).collect(Collectors.toList());
                //找出被删除的id
                Collection collection = new ArrayList(oldIds);
                collection.removeAll(newIds);
                if(collection.size() > 0){
                    //遍历删除被删除的明细
                    Iterator<Integer> ids = collection.iterator();
                    while (ids.hasNext()){
                        int detailId = ids.next();

                        //添加日志
                        TaskProductEntity detailEntity = taskProductService.queryById(detailId);
                        //新增日志信息
                        DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
                        //模块主表id
                        dataInfoLog.setParentId(id);
                        //模块id
                        dataInfoLog.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
                        //操作人编码
                        dataInfoLog.setOperationCode(createNo);
                        //操作人名称
                        dataInfoLog.setOperationName(creator);
                        //操作类型
                        dataInfoLog.setOperationType(OperationTypeEnum.DELETE_DATA.getId());
                        //操作时间
                        dataInfoLog.setOperationTime(new Date());
                        //操作内容
                        dataInfoLog.setOperationContent("产品信息:" + "产品编码:" + detailEntity.getProductCode() + ",规格编码:" + detailEntity.getSpecificationCode());

                        dataInfoLogService.insert(dataInfoLog);

                        TaskProductEntity detail = new TaskProductEntity();
                        detail.setId(detailId);
                        detail.setValid(DataIsValidEnum.INVALID.getId());
                        //将删除的明细设为无效
                        taskProductService.update(detail);

                        //获取对应的配件数据
                        TaskProductPartsEntity query = new TaskProductPartsEntity();
                        //报价id
                        query.setParentId(id);
                        //产品明细id
                        query.setDetailId(detailId);
                        //有效的数据
                        query.setValid(DataIsValidEnum.VALID.getId());
                        //调用接口查询
                        List<TaskProductPartsEntity> partsList = taskProductPartsService.queryAll(query);
                        if(!CollectionUtils.isEmpty(partsList)){
                            for(TaskProductPartsEntity partsEntity : partsList){
                                TaskProductPartsEntity updateReq = new TaskProductPartsEntity();
                                //修改主键
                                updateReq.setId(partsEntity.getId());
                                //修改时间
                                updateReq.setModifyTime(new Date());
                                //设为无效
                                updateReq.setValid(DataIsValidEnum.INVALID.getId());

                                taskProductPartsService.update(updateReq);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 处理被删除的配件
     * @param id 产品明细id
     * @param newIds 配件id
     */
    private void handleBeenDeletedParts(int id, List<Integer> newIds){
        //修改-找出被删除的明细

        TaskProductPartsEntity partsReq = new TaskProductPartsEntity();
        //设置产品明细id
        partsReq.setDetailId(id);
        //查询有效数据
        partsReq.setValid(DataIsValidEnum.VALID.getId());
        //调用接口查询结果
        List<TaskProductPartsEntity> partsList = taskProductPartsService.queryAll(partsReq);
        if(!CollectionUtils.isEmpty(partsList)){
            //获取id集合
            List<Integer> oldIds = partsList.stream().map(p -> p.getId()).collect(Collectors.toList());
            //找出被删除的id
            Collection collection = new ArrayList(oldIds);
            collection.removeAll(newIds);
            if(collection.size() > 0){
                //遍历删除被删除的明细
                Iterator<Integer> ids = collection.iterator();
                while (ids.hasNext()){
                    int partsId = ids.next();
                    TaskProductPartsEntity updateReq = new TaskProductPartsEntity();
                    //修改主键
                    updateReq.setId(partsId);
                    //修改时间
                    updateReq.setModifyTime(new Date());
                    //设为无效
                    updateReq.setValid(DataIsValidEnum.INVALID.getId());

                    taskProductPartsService.update(updateReq);

                }
            }
        }
    }

    /**
     * 校验单号是否存在
     * @param billNo 单号
     * @return true:不重复 false:重复
     */
    private boolean checkRepeatBillNo(String billNo){
        TaskEntity req = new TaskEntity();
        req.setBillNo(billNo);
        req.setValid(DataIsValidEnum.VALID.getId());
        List<TaskEntity> taskEntities = taskService.queryAll(req);
        if(CollectionUtils.isEmpty(taskEntities)){
            return true;
        }
        return false;
    }

    /**
     * 新增主表信息
     * @param req 新增参数
     * @param creator 创建人
     * @param createNo 创建人编码
     * @return 主表id
     * @throws ParseException
     */
    private Integer insert(AddTaskReq req, String creator, String createNo) throws ParseException {
        //初始化对象
        TaskEntity contract = new TaskEntity();
        //赋值
        BeanUtils.copyProperties(req, contract);
        //签约日期
        contract.setSigningDate(DateUtils.convertStringToDate(req.getSigningDate(), DateUtils.DATE_PATTERN));
        //出运日期
        contract.setCarryTime(DateUtils.convertStringToDate(req.getCarryTime(), DateUtils.DATE_PATTERN));
        //付款日期
        contract.setPaymentTerm(DateUtils.convertStringToDate(req.getPaymentTerm(), DateUtils.DATE_PATTERN));
        //保存后进草稿箱
        contract.setStatus(OperationStatusEnum.DRAFT_BOX.getId());
        //设置数据有效性(0:无效 1:有效)
        contract.setValid(DataIsValidEnum.VALID.getId());
        //设置创建时间
        contract.setCreateDate(new Date());

        if(null == req.getId()){
            //新增
            //设置创建人
            contract.setOperator(creator);
            //设置创建人编码
            contract.setOperationCode(createNo);
            //调用接口新增调拨
            return taskService.insert(contract) == 1 ? contract.getId() : null;
        }else {
            //修改

            //如果明细、费用为空，则删除对应所有明细和费用
            if(CollectionUtils.isEmpty(req.getDetailList())){
                TaskProductEntity detailReq = new TaskProductEntity();
                //设置id
                detailReq.setParentId(req.getId());
                //数据有效
                detailReq.setValid(DataIsValidEnum.VALID.getId());
                List<TaskProductEntity> detailList = taskProductService.queryAll(detailReq);
                if(!CollectionUtils.isEmpty(detailList)){
                    for(TaskProductEntity detail : detailList){
                        TaskProductEntity updateReq = new TaskProductEntity();
                        //主键id
                        updateReq.setId(detail.getId());
                        //设为无效
                        updateReq.setValid(DataIsValidEnum.INVALID.getId());

                        taskProductService.update(updateReq);
                    }
                }
            }

            if(CollectionUtils.isEmpty(req.getCostList())){
                TaskCostEntity costReq = new TaskCostEntity();
                //设置id
                costReq.setParentId(req.getId());
                //数据有效
                costReq.setValid(DataIsValidEnum.VALID.getId());
                List<TaskCostEntity> costList = taskCostService.queryAll(costReq);
                if(!CollectionUtils.isEmpty(costList)){
                    for(TaskCostEntity cost : costList){
                        TaskCostEntity updateReq = new TaskCostEntity();
                        //主键id
                        updateReq.setId(cost.getId());
                        //修改时间
                        updateReq.setModifyTime(new Date());
                        //设为无效
                        updateReq.setValid(DataIsValidEnum.INVALID.getId());

                        taskCostService.update(updateReq);
                    }
                }
            }
            //设置修改时间
            contract.setModifyTime(new Date());

            //添加修改日志
            //获取修改前对象数据
            TaskEntity oldData = taskService.queryById(req.getId());
            BeanChangeLogUtil logUtil = new BeanChangeLogUtil();
            String info = logUtil.contrastObj(oldData, contract);
            if(StringUtils.isNotEmpty(info)) {
                //新增日志信息
                DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
                //模块主表id
                dataInfoLog.setParentId(req.getId());
                //模块id
                dataInfoLog.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
                //操作人编码
                dataInfoLog.setOperationCode(createNo);
                //操作人名称
                dataInfoLog.setOperationName(creator);
                //操作类型
                dataInfoLog.setOperationType(OperationTypeEnum.UPDATE_DATA.getId());
                //操作时间
                dataInfoLog.setOperationTime(new Date());
                //操作内容
                dataInfoLog.setOperationContent("主信息:" + info);

                dataInfoLogService.insert(dataInfoLog);
            }

            return taskService.update(contract) == 1 ? contract.getId() : null;
        }

    }

    /**
     * 任务分页查询
     * @param req 查询参数
     * @return 任务信息
     */
    public PageInfo<TaskPageListVo> getListByPage(TaskPageListReq req){
        //初始化回参对象集合
        List<TaskPageListVo> voList = new ArrayList<>();
        if(StringUtils.isBlank(req.getOperationCode()) && StringUtils.isBlank(req.getSalesmanCode()) && StringUtils.isBlank(req.getDeptSalesmanCode()) && StringUtils.isBlank(req.getDeptOperationCode())){
            PageInfo pageInfo = new PageInfo();
            pageInfo.setList(voList);
            return pageInfo;
        }
        //初始化查询对象
        TaskPageListInfoReq query = new TaskPageListInfoReq();
        //赋值
        BeanUtils.copyProperties(req, query);
        if(StringUtils.isNotEmpty(req.getBillNo())){
            //去掉前后空格
            query.setBillNo(req.getBillNo().trim());
        }
        //调用接口查询结果
        List<TaskEntity> contractList = taskService.getTaskListInfo(query);
        PageInfo pageInfo = new PageInfo(contractList);
        if(CollectionUtils.isEmpty(contractList)){
            pageInfo.setList(voList);
            return pageInfo;
        }
        for(TaskEntity contract : contractList){
            TaskPageListVo vo = new TaskPageListVo();
            //赋值
            BeanUtils.copyProperties(contract, vo);
            //签约日期
            vo.setSigningDate(DateUtils.format(contract.getSigningDate(), DateUtils.DATE_PATTERN));
            //出运日期
            vo.setCarryTime(DateUtils.format(contract.getCarryTime(), DateUtils.DATE_PATTERN));
            //付款期限
            vo.setPaymentTerm(DateUtils.format(contract.getPaymentTerm(), DateUtils.DATE_PATTERN));
            //状态
            vo.setStatusStr(OperationStatusEnum.getDescById(contract.getStatus()));

            voList.add(vo);
        }

        pageInfo.setList(voList);
        return pageInfo;
    }

    /**
     * 任务查询
     * @param req 查询参数
     * @return 任务信息
     */
    public List<TaskPageListVo> getList(TaskPageListReq req){
        //初始化回参对象集合
        List<TaskPageListVo> voList = new ArrayList<>();
        //初始化查询对象
        TaskPageListInfoReq query = new TaskPageListInfoReq();
        //赋值
        BeanUtils.copyProperties(req, query);
        if(StringUtils.isNotEmpty(req.getBillNo())){
            //去掉前后空格
            query.setBillNo(req.getBillNo().trim());
        }
        //调用接口查询结果
        List<TaskEntity> contractList = taskService.getTaskListInfo(query);
        if(CollectionUtils.isEmpty(contractList)){
            return voList;
        }
        for(TaskEntity contract : contractList){
            TaskPageListVo vo = new TaskPageListVo();
            //赋值
            BeanUtils.copyProperties(contract, vo);
            //签约日期
            vo.setSigningDate(DateUtils.format(contract.getSigningDate(), DateUtils.DATE_PATTERN));
            //出运日期
            vo.setCarryTime(DateUtils.format(contract.getCarryTime(), DateUtils.DATE_PATTERN));
            //付款期限
            vo.setPaymentTerm(DateUtils.format(contract.getPaymentTerm(), DateUtils.DATE_PATTERN));
            //状态
            vo.setStatusStr(OperationStatusEnum.getDescById(contract.getStatus()));

            voList.add(vo);
        }

        return voList;
    }

    /**
     * 详情
     * @param id 任务id
     * @return 任务详情
     */
    public TaskDetailVo detail(Integer id){
        //初始化回参对象
        TaskDetailVo vo = new TaskDetailVo();
        if(null == id){
            return vo;
        }
        //第一步：获取主表信息
        TaskEntity contract = taskService.queryById(id);
        if(null == contract || null == contract.getId()){
            return vo;
        }
        //赋值
        BeanUtils.copyProperties(contract, vo);
        //签约日期
        vo.setSigningDate(DateUtils.format(contract.getSigningDate(), DateUtils.DATE_PATTERN));
        //出运日期
        vo.setCarryTime(DateUtils.format(contract.getCarryTime(), DateUtils.DATE_PATTERN));
        //付款期限
        vo.setPaymentTerm(DateUtils.format(contract.getPaymentTerm(), DateUtils.DATE_PATTERN));
        //充值占用(0:否 1:是)
        if(null != contract.getRechargeOccupancy()){
            vo.setRechargeOccupancyStr(contract.getRechargeOccupancy() == 1 ? "是" : "否");
        }
        if(null != contract.getIsDeclare()){
            //是否报关(0:否 1:是)
            vo.setIsDeclareStr(contract.getIsDeclare() == 1 ? "是" : "否");
        }

        //第二步：获取产品明细数据
        TaskProductEntity contractDetailReq = new TaskProductEntity();
        //外销id
        contractDetailReq.setParentId(id);
        //有效数据
        contractDetailReq.setValid(DataIsValidEnum.VALID.getId());
        //调用接口查询产品明细数据
        List<TaskProductEntity> contractDetailList = taskProductService.queryAll(contractDetailReq);
        if(!CollectionUtils.isEmpty(contractDetailList)){
            //初始化回参对象集合
            List<TaskProductDetailVo> detailList = new ArrayList<>();
            for(TaskProductEntity detailEntity : contractDetailList){
                //初始化回参对象
                TaskProductDetailVo productDetailVo = new TaskProductDetailVo();
                //赋值
                BeanUtils.copyProperties(detailEntity, productDetailVo);
                //交货日期
                productDetailVo.setDeliveryDate(DateUtils.format(detailEntity.getDeliveryDate()));
                //校验该产品在下游是否被调用 true:未被调用 false:已被调用
                BigDecimal sum = getUsedQuantity(contract.getBillNo(), detailEntity.getProductCode(), detailEntity.getSpecificationCode(), detailEntity.getId());
                if(sum.compareTo(BigDecimal.ZERO) == 1){
                    //已被调用，不能删除
                    productDetailVo.setIsDelete(1);
                    //设置已被调用数量
                    productDetailVo.setUsedQuantity(sum);
                }else {
                    //未被调用，可删除
                    productDetailVo.setIsDelete(0);
                }
                //获取对应配件信息
                TaskProductPartsEntity partsReq = new TaskProductPartsEntity();
                //设置报价id
                partsReq.setParentId(id);
                //设置产品明细id
                partsReq.setDetailId(detailEntity.getId());
                //设置数据有效性
                partsReq.setValid(DataIsValidEnum.VALID.getId());
                //查询结果
                List<TaskProductPartsEntity> partsEntityList = taskProductPartsService.queryAll(partsReq);
                if(!CollectionUtils.isEmpty(partsEntityList)){
                    List<TaskProductPartsDetailVo> partsList = partsEntityList.stream().map(p ->{
                        TaskProductPartsDetailVo partsVo = new TaskProductPartsDetailVo();
                        //赋值
                        BeanUtils.copyProperties(p, partsVo);
                        return partsVo;
                    }).collect(Collectors.toList());

                    //添加相关配件集合
                    productDetailVo.setPartsList(partsList);
                }

                detailList.add(productDetailVo);
            }
            //添加产品明细数据
            vo.setDetailList(detailList);
        }

        //第三步：获取费用数据
        TaskCostEntity costReq = new TaskCostEntity();
        //设置报价id
        costReq.setParentId(id);
        //获取有效数据
        costReq.setValid(DataIsValidEnum.VALID.getId());
        //查询结果
        List<TaskCostEntity> costEntities = taskCostService.queryAll(costReq);
        if(!CollectionUtils.isEmpty(costEntities)){
            List<TaskCostDetailVo> costList = costEntities.stream().map(p ->{
                TaskCostDetailVo costVo = new TaskCostDetailVo();
                //赋值
                BeanUtils.copyProperties(p, costVo);
                return costVo;
            }).collect(Collectors.toList());

            //添加相关费用信息
            vo.setCostList(costList);
        }

        //第四步：获取对应附件信息
        AnnexEntity annex = new AnnexEntity();
        //设置模块id
        annex.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
        //设置父id
        annex.setParentId(id);
        //设置数据有效
        annex.setValid(DataIsValidEnum.VALID.getId());
        //调用接口查询附件信息
        List<AnnexEntity> annexList = annexService.queryAll(annex);
        if (!CollectionUtils.isEmpty(annexList)) {
            List<AnnexVo> annexVos = annexList.stream().map(p -> {
                AnnexVo annexVo = new AnnexVo();
                //赋值
                BeanUtils.copyProperties(p, annexVo);
                //上传时间转换
                annexVo.setUploadTime(DateUtils.format(p.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
                //设置附件为旧附件,用以区分修改时附件状态
                annexVo.setNews(0);

                return annexVo;
            }).collect(Collectors.toList());

            vo.setAnnexList(annexVos);
        }

        //第五步：获取对应日志信息
        DataInfoLogEntity logReq = new DataInfoLogEntity();
        //主表id
        logReq.setParentId(id);
        //模块id
        logReq.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
        //查询结果
        List<DataInfoLogEntity> dataInfoLog = dataInfoLogService.queryAll(logReq);
        if(!CollectionUtils.isEmpty(dataInfoLog)){
            List<DataInfoLogVo> logVos = new ArrayList<>();
            for(DataInfoLogEntity log : dataInfoLog){
                DataInfoLogVo logVo = new DataInfoLogVo();
                //赋值
                BeanUtils.copyProperties(log, logVo);
                //日期处理
                logVo.setOperationTime(DateUtils.format(log.getOperationTime(), DateUtils.DATE_TIME_PATTERN));
                //操作类型
                logVo.setOperationType(OperationTypeEnum.getDescById(log.getOperationType()));

                logVos.add(logVo);
            }

            vo.setLogList(logVos);
        }

        return vo;
    }

    /**
     * 删除
     * @param req
     */
    public void delete(OperationReq req){
        if(null == req.getId() || null == req.getStatus()){
            return;
        }
        TaskEntity contractReq = new TaskEntity();
        contractReq.setId(req.getId());
        contractReq.setModifyTime(new Date());
        if(req.getStatus().equals(OperationStatusEnum.DRAFT_BOX.getId())){
            //草稿箱删除,数位改为垃圾箱
            contractReq.setStatus(OperationStatusEnum.TRASH_CAN.getId());
            taskService.update(contractReq);
            return;
        }else {
            //垃圾箱删除,将主数据设为无效
            contractReq.setValid(DataIsValidEnum.INVALID.getId());
            taskService.update(contractReq);
        }
        //获取对应明细数据
        TaskProductEntity detailEntity = new TaskProductEntity();
        detailEntity.setParentId(req.getId());
        detailEntity.setValid(DataIsValidEnum.VALID.getId());

        List<TaskProductEntity> detailList = taskProductService.queryAll(detailEntity);
        if(CollectionUtils.isEmpty(detailList)){
            return;
        }
        //将所有对应有效的明细数据设为无效
        for(TaskProductEntity detail : detailList){
            TaskProductEntity detailReq = new TaskProductEntity();
            detailReq.setId(detail.getId());
            detailReq.setValid(DataIsValidEnum.INVALID.getId());

            taskProductService.update(detailReq);
        }

        //获取费用数据
        TaskCostEntity costEntity = new TaskCostEntity();
        costEntity.setParentId(req.getId());
        costEntity.setValid(DataIsValidEnum.VALID.getId());

        List<TaskCostEntity> costList = taskCostService.queryAll(costEntity);
        if(CollectionUtils.isEmpty(costList)){
            return;
        }
        //将所有对应有效的费用数据设为无效
        for(TaskCostEntity cost : costList){
            TaskCostEntity costReq = new TaskCostEntity();
            costReq.setId(cost.getId());
            costReq.setModifyTime(new Date());
            costReq.setValid(DataIsValidEnum.INVALID.getId());

            taskCostService.update(costReq);
        }

        //获取对应所有附件
        AnnexEntity annex = new AnnexEntity();
        annex.setModuleId(ModuleTypeEnum.BUSINESS_TASK.getId());
        annex.setParentId(req.getId());
        annex.setValid(DataIsValidEnum.VALID.getId());
        List<AnnexEntity> annexList = annexService.queryAll(annex);
        if(CollectionUtils.isEmpty(annexList)){
            return;
        }
        //删除所有对应的有效的附件
        for(AnnexEntity annexData : annexList){
            AnnexEntity annexReq = new AnnexEntity();
            annexReq.setId(annexData.getId());
            annexReq.setUpdateTime(new Date());
            annexReq.setValid(DataIsValidEnum.INVALID.getId());

            annexService.update(annexReq);
        }
    }

    /**
     * 箱体操作
     * @param req
     */
    public R operation(OperationReq req){
        if(null == req.getId() || null == req.getOperation() || StringUtils.isBlank(req.getBillNo())){
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        TaskEntity exportContractEntity = new TaskEntity();
        //设置修改主键
        exportContractEntity.setId(req.getId());
        //修改时间
        exportContractEntity.setModifyTime(new Date());

        switch (req.getOperation()){
            case 1:
                //提交审批后,状态为待批箱
                exportContractEntity.setStatus(OperationStatusEnum.PENDING_BOX.getId());
                break;
            case 2:
                //审批通过,状态设为已批箱
                exportContractEntity.setStatus(OperationStatusEnum.APPROVED_BOX.getId());
                break;
            case 3:
                //审批退回
                //校验是否可以回退数据 true:是 false:否
                boolean flag = checkDataIsRollBack(req.getId(), req.getBillNo());
                if(flag){
                    //状态设为草稿箱
                    exportContractEntity.setStatus(OperationStatusEnum.DRAFT_BOX.getId());
                }else {
                    //审批退回失败,存在已被调用的产品
                    return R.buildError(ResultStatusEnum.APPROVAL_RETURNED_FAILED);
                }
                break;
            case 4:
                //将状态设为完成
                exportContractEntity.setStatus(OperationStatusEnum.COMPLETION_BOX.getId());
                break;
            case 5:
                //点击还原，将状态改为草稿箱
                exportContractEntity.setStatus(OperationStatusEnum.DRAFT_BOX.getId());
                break;
        }
        //调用接口修改
        taskService.update(exportContractEntity);
        return R.buildError(ResultStatusEnum.SUCCESS);
    }

    /**
     * 导入-获取备货主表信息
     * @param req 查询条件入参实体
     * @return 备货主表信息
     */
    public PageInfo<ImportTaskVo> getTaskByPage(ImportTaskReq req){
        //初始化回参对象集合
        List<ImportTaskVo> voList = new ArrayList<>();
        if(StringUtils.isBlank(req.getBillNo()) &&
                StringUtils.isBlank(req.getCustomerContactNo()) &&
                StringUtils.isBlank(req.getCustomerName()) &&
                StringUtils.isBlank(req.getSigningDateEnd()) &&
                StringUtils.isBlank(req.getSigningDateStart()) &&
                StringUtils.isBlank(req.getDeptSalesmanCode()) &&
                null == req.getIsDeclare()){
            PageInfo pageInfo = new PageInfo();
            pageInfo.setList(voList);
            return pageInfo;

        }
        //初始化查询对象
        ImportTaskInfoReq queryReq = new ImportTaskInfoReq();
        //字段赋值
        BeanUtils.copyProperties(req, queryReq);
        //调用接口查询结果
        List<TaskEntity> resList = taskService.queryImportTaskInfo(queryReq);
        //获取分页信息
        PageInfo pageInfo = new PageInfo(resList);
        if(CollectionUtils.isEmpty(resList)){
            pageInfo.setList(voList);
            return pageInfo;
        }
        for(TaskEntity res : resList){
            //初始化回参对象
            ImportTaskVo vo = new ImportTaskVo();
            //字段赋值
            BeanUtils.copyProperties(res, vo);
            //签约日期
            vo.setSigningDate(DateUtils.format(res.getSigningDate(), DateUtils.DATE_PATTERN));
            //出运日期
            vo.setCarryTime(DateUtils.format(res.getCarryTime(), DateUtils.DATE_PATTERN));
            //付款期限
            vo.setPaymentTerm(DateUtils.format(res.getPaymentTerm(), DateUtils.DATE_PATTERN));

            voList.add(vo);
        }
        pageInfo.setList(voList);

        return pageInfo;
    }

    /**
     * 导入-获取备货产品信息
     * @param id 备货主表id
     * @return 备货产品信息
     */
    public PageInfo<ImportTaskProductVo> getTaskProductByPage(Integer id){
        //调用接口查询结果
        List<ImportTaskProductRsp> resList = taskProductService.queryByParentId(id);
        //获取分页信息
        PageInfo pageInfo = new PageInfo(resList);
        //初始化回参对象集合
        List<ImportTaskProductVo> voList = new ArrayList<>();
        if(CollectionUtils.isEmpty(resList)){
            pageInfo.setList(voList);
            return pageInfo;
        }
        pageInfo.setList(getTaskProductList(resList));

        return pageInfo;
    }

    /**
     * 导入-获取备货产品信息(不分页)
     * @param id 备货主表id
     * @return 备货产品信息
     */
    public List<ImportTaskProductVo> getTaskProduct(Integer id){
        //调用接口查询结果
        List<ImportTaskProductRsp> resList = taskProductService.queryByParentId(id);
        List<ImportTaskProductVo> voList = new ArrayList<>();
        if(CollectionUtils.isEmpty(resList)){
            return voList;
        }
        return getTaskProductList(resList);
    }

    /**
     * 剔除已做计划数量
     * @param resList 备货信息
     * @return 剔除已做计划信息
     */
    private List<ImportTaskProductVo> getTaskProductList(List<ImportTaskProductRsp> resList){
        List<ImportTaskProductVo> voList = new ArrayList<>();
        for(ImportTaskProductRsp res : resList){
            //获取该外销单据已做过的出运计划数量
            int count = shipmentPlanService.getPlanProductNum(res.getSalesContractNo(), res.getProductCode(), res.getSpecificationCode(), res.getId());
            BigDecimal newCount = new BigDecimal(Integer.toString(count));
            //获取当前单据产品数量
            BigDecimal productNum = res.getProductNum();
            //剩余数量
            BigDecimal resCount = productNum.subtract(newCount);
            if(resCount.compareTo(BigDecimal.ZERO) == 1){
                //获取剩余数量大于零数据
                //初始化回参对象
                ImportTaskProductVo vo = new ImportTaskProductVo();
                //字段赋值
                BeanUtils.copyProperties(res, vo);
                //新的数量
                vo.setProductNum(resCount);

                voList.add(vo);
            }

        }
        return voList;
    }

    /**
     * 导入-获取备货产品配件信息
     * @param id 备货产品id
     * @return 备货产品配件信息
     */
    public PageInfo<ImportTaskProductPartsVo> getTaskProductPartsByPage(Integer id){
        //调用接口查询结果
        List<ImportTaskProductPartsRsp> resList = taskProductPartsService.queryByParentId(id);
        //获取分页信息
        PageInfo pageInfo = new PageInfo(resList);
        //初始化回参对象集合
        List<ImportTaskProductPartsVo> voList = new ArrayList<>();
        if(CollectionUtils.isEmpty(resList)){
            pageInfo.setList(voList);
            return pageInfo;
        }
        pageInfo.setList(getTaskProductPartsList(resList));

        return pageInfo;
    }

    /**
     * 导入-获取备货产品配件信息(不分页)
     * @param id 备货产品id
     * @return 备货产品配件信息
     */
    public List<ImportTaskProductPartsVo> getTaskProductParts(Integer id){
        //调用接口查询结果
        List<ImportTaskProductPartsRsp> resList = taskProductPartsService.queryByParentId(id);
        //初始化回参对象集合
        List<ImportTaskProductPartsVo> voList = new ArrayList<>();
        if(CollectionUtils.isEmpty(resList)){
            return voList;
        }

        return getTaskProductPartsList(resList);
    }

    /**
     * 处理配件集合
     * @param resList 配件集合
     * @return 处理后的配件集合
     */
    private List<ImportTaskProductPartsVo> getTaskProductPartsList(List<ImportTaskProductPartsRsp> resList){
        //初始化回参对象集合
        List<ImportTaskProductPartsVo> voList = new ArrayList<>();
        for(ImportTaskProductPartsRsp res : resList){
            //初始化回参对象
            ImportTaskProductPartsVo vo = new ImportTaskProductPartsVo();
            //字段赋值
            BeanUtils.copyProperties(res, vo);

            voList.add(vo);
        }
        return voList;
    }

    /**
     * 获取当月备货量
     * @param name 操作员
     * @param code 操作员编码
     * @return 当月备货量
     */
    public long getTaskCount(String name, String code){
        //初始化查询对象
        StatisticsInfoReq infoReq = new StatisticsInfoReq();
        infoReq.setOperator(name);
        infoReq.setOperationCode(code);
        infoReq.setCreateDateStart(DateUtils.format(DateUtils.getStartTimeOfTheMonth(), DateUtils.DATE_PATTERN));
        infoReq.setCreateDateEnd(DateUtils.format(DateUtils.getEndTimeOfTheMonth(), DateUtils.DATE_PATTERN));
        //查询结果
        return taskService.getTaskCount(infoReq);
    }

    /**
     * 获取被下游调用的产品数量
     * @param billNo 外销合同号
     * @param productCode 产品编码
     * @param detailId 明细id
     * @param specificationCode 规格编码
     * @return 下游调用的产品数量
     */
    private BigDecimal getUsedQuantity(String billNo, String productCode, String specificationCode, Integer detailId){
        //初始化查询参数
        RemainingQuantityReq req = new RemainingQuantityReq();
        //报价单号
        req.setBillNo(billNo);
        //产品编码
        req.setProductCode(productCode);
        //规格编码
        req.setSpecificationCode(specificationCode);
        //调用接口查询该产品在采购中的数量
        BigDecimal sumPurchase = exportContractProductService.getPurchaseInfo(req);
        if(sumPurchase.compareTo(BigDecimal.ZERO) == 1){
            return sumPurchase;
        }

        //调用接口查询该产品在出运计划中的数量
        int count = shipmentPlanService.getPlanProductNum(billNo, productCode, specificationCode, detailId);
        if(count > 0){
            return new BigDecimal(String.valueOf(count));
        }

        return new BigDecimal("0");
    }

    /**
     * 校验是否可以回退数据 true:是 false:否
     * @param id 备货id
     * @param billNo 备货单号
     * @return 是否可以回退数据
     */
    private Boolean checkDataIsRollBack(Integer id, String billNo){
        TaskProductEntity product = new TaskProductEntity();
        //设置父id
        product.setParentId(id);
        //设置数据有效
        product.setValid(DataIsValidEnum.VALID.getId());
        //获取报价产品信息
        List<TaskProductEntity> detailList = taskProductService.queryAll(product);
        if(CollectionUtils.isEmpty(detailList)){
            return true;
        }
        for(TaskProductEntity detail : detailList){
            //校验该产品在下游是否被调用 true:未被调用 false:已被调用
            boolean status = checkProductIsUsed(billNo, detail.getProductCode(), detail.getSpecificationCode(), product.getId());
            if(!status){
                return false;
            }

        }
        return true;
    }

    /**
     * 校验该产品在下游是否被调用
     * @param billNo 备货单号
     * @param productCode 产品编码
     * @param specificationCode 规格编码
     * @param detailId 明细id
     * @return true:未被调用 false:已被调用
     */
    private Boolean checkProductIsUsed(String billNo, String productCode, String specificationCode, Integer detailId){
        //初始化查询参数
        RemainingQuantityReq req = new RemainingQuantityReq();
        //备货单号
        req.setBillNo(billNo);
        //产品编码
        req.setProductCode(productCode);
        //规格编码
        req.setSpecificationCode(specificationCode);
        //调用接口查询该产品在采购中的数量
        BigDecimal sumPurchase = exportContractProductService.getPurchaseInfo(req);
        if(sumPurchase.compareTo(BigDecimal.ZERO) == 1){
            return false;
        }

        //调用接口查询该产品在出运计划中的数量
        int count = shipmentPlanService.getPlanProductNum(billNo, productCode, specificationCode, detailId);
        if(count > 0){
            return false;
        }
        return true;
    }

    /**
     * 获取String类型不为空数据
     * @param value 目标数据
     * @return 不为空数据
     */
    private String getNotNullOfStringInfo(String value){
        if(StringUtils.isEmpty(value)){
            return "";
        }else {
            return value;
        }
    }

    /**
     * 获取BigDecimal类型不为空的数据
     * @param value 目标数据
     * @return 不为空数据
     */
    private BigDecimal getNotNullOfBigDecimalInfo(BigDecimal value){
        if(StringUtil.isNotEmpty(value)){
            return value;
        }else {
            return new BigDecimal("0");
        }
    }
    /**
     * 任务(备货合同)产品交期一览表-集合
     * @param req
     * @return
     */
    private List<QueryTaskStatisticsOneRes> taskStatistics1ResList(QueryTaskStatisticsOneReq req){
        List<QueryTaskStatisticsOneRes> taskStatistics1ResList=taskService.getTaskStatisticsOneList(req);

        for (QueryTaskStatisticsOneRes p: taskStatistics1ResList) {
            p.setContractDeliveryDateStr(DateUtils.format(p.getContractDeliveryDate(),DateUtils.DATE_PATTERN));
            p.setContractSigningDateStr(DateUtils.format(p.getContractSigningDate(),DateUtils.DATE_PATTERN));
            p.setPurchaseDeliveryDateStr(DateUtils.format(p.getPurchaseDeliveryDate(),DateUtils.DATE_PATTERN));
            p.setPurchaseSigningDateStr(DateUtils.format(p.getPurchaseSigningDate(),DateUtils.DATE_PATTERN));
            if (p.getCarryNum()==null){
                p.setCarryNum(new BigDecimal(0));
            }
            p.setUnCarryNum(p.getProductNum().subtract(p.getCarryNum()));
        }

        return taskStatistics1ResList;
    }
    /**
     * 任务(备货合同)产品交期一览表-分页
     * @param req
     * @return
     */
    public PageInfo<QueryTaskStatisticsOneRes> getTaskStatisticsOneListByPage(QueryTaskStatisticsOneReq req){
        List<QueryTaskStatisticsOneRes> taskStatistics1ResList=taskStatistics1ResList(req);
        PageInfo<QueryTaskStatisticsOneRes> pageInfo=new PageInfo<>(taskStatistics1ResList);
        return pageInfo;
    }
    /**
     * 任务(备货合同)产品交期一览表-导出
     * @param req
     * @return
     */
    public JSONObject getTaskStatisticsOneListExport(QueryTaskStatisticsOneReq req){
        List<QueryTaskStatisticsOneRes> taskStatistics1ResList=taskStatistics1ResList(req);
        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleTaskOneInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if(CollectionUtils.isEmpty(taskStatistics1ResList)){
            obj.put("data", data);
            return obj;
        }
        excelTaskOneInfoExport(data,taskStatistics1ResList);
        obj.put("data", data);
        return obj;
    }
    private JSONArray getTitleTaskOneInfo(){
        JSONArray obj=new JSONArray();
        obj.add("业务员");
        obj.add("采购员");
        obj.add("任务合同签约日期");
        obj.add("任务(备货)单号");
        obj.add("采购单号");
        obj.add("采购合同签约日期");
        obj.add("产品编码");
        obj.add("规格编码");
        obj.add("任务要求交期");
        obj.add("中文描述");
        obj.add("英文描述");
        obj.add("采购回馈交期");
        obj.add("产品数量");

        obj.add("已出货数量");
        obj.add("未出货数量");
        obj.add("出货目的地");
        obj.add("箱型40HQ`20GP`LCL`(空运 or 海运)");
        obj.add("本月计划数量");
        obj.add("需求提出日期");
        obj.add("供出商实际出货日期");
        return obj;
    }

    private void excelTaskOneInfoExport(JSONArray data,List<QueryTaskStatisticsOneRes> list){
        for (QueryTaskStatisticsOneRes vo:list){
            JSONArray infoList = new JSONArray();
            infoList.add(getNotNullOfStringInfo(vo.getSalesmanName()));
            infoList.add(getNotNullOfStringInfo(vo.getOperatorName()));
            infoList.add(getNotNullOfStringInfo(vo.getContractSigningDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getContractNo()));
            infoList.add(getNotNullOfStringInfo(vo.getPurchaseOrderNo()));
            infoList.add(getNotNullOfStringInfo(vo.getPurchaseSigningDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSpecCode()));
            infoList.add(getNotNullOfStringInfo(vo.getContractDeliveryDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getChineseDesc()));
            infoList.add(getNotNullOfStringInfo(vo.getEnglishDesc()));
            infoList.add(getNotNullOfStringInfo(vo.getPurchaseDeliveryDateStr()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProductNum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCarryNum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUnCarryNum()));
            infoList.add(getNotNullOfStringInfo(vo.getDestinationName()));
            infoList.add(getNotNullOfStringInfo(vo.getContainerType()));
            infoList.add("");
            infoList.add("");
            infoList.add("");
            infoList.add("");
            data.add(infoList);
        }
    }




    /**
     * 备货采购情况-集合
     * @param req
     * @return
     */
    private List<QueryTaskStatisticsTwoRes> taskPurchaseStatisticsList(QueryTaskStatisticsTwoReq req){
        List<QueryTaskStatisticsTwoRes> resList=taskService.getTaskPurchaseStatisticsList(req);

        for (QueryTaskStatisticsTwoRes p: resList) {
            p.setPurSignDateStr(DateUtils.format(p.getPurchaseSigningDate(),DateUtils.DATE_PATTERN));
            p.setContractSignDateStr(DateUtils.format(p.getContractSigningDate(),DateUtils.DATE_PATTERN));
            p.setPurDelDateStr(DateUtils.format(p.getPurchaseDeliveryDate(),DateUtils.DATE_PATTERN));
            p.setPurFeeDelDateStr(DateUtils.format(p.getPurchaseFeedbackDeliveryDate(),DateUtils.DATE_PATTERN));
            if (p.getPurchaseNum()==null){
                p.setPurchaseNum(new BigDecimal(0));
            }
            p.setUnPurchaseNum(p.getProductNum().subtract(p.getPurchaseNum()));

            switch (p.getStatus()){
                case 1:
                    p.setStatusStr("草稿箱");
                    break;
                case 2:
                    p.setStatusStr("待批箱");
                    break;
                case 3:
                    p.setStatusStr("已批箱");
                    break;
                case 4:
                    p.setStatusStr("完成箱");
                    break;
                case 5:
                    p.setStatusStr("垃圾箱");
                    break;
            }

        }

        return resList;
    }
    /**
     * 备货采购情况-分页
     * @param req
     * @return
     */
    public PageInfo<QueryTaskStatisticsTwoRes> getTaskPurchaseStatisticsListByPage(QueryTaskStatisticsTwoReq req){
        List<QueryTaskStatisticsTwoRes> taskStatistics1ResList=taskPurchaseStatisticsList(req);
        PageInfo<QueryTaskStatisticsTwoRes> pageInfo=new PageInfo<>(taskStatistics1ResList);
        return pageInfo;
    }
    /**
     * 备货采购情况-导出
     * @param req
     * @return
     */
    public JSONObject getTaskPurchaseStatisticsListExport(QueryTaskStatisticsTwoReq req){
        List<QueryTaskStatisticsTwoRes> resList=taskPurchaseStatisticsList(req);
        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleTaskPurchaseInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if(CollectionUtils.isEmpty(resList)){
            obj.put("data", data);
            return obj;
        }
        excelTitleTaskInfoExport(data,resList);
        obj.put("data", data);
        return obj;
    }
    private JSONArray getTitleTaskPurchaseInfo(){
        JSONArray obj=new JSONArray();
        obj.add("单据类型");
        obj.add("备货合同号");
        obj.add("合同签约日期");
        obj.add("业务员");
        obj.add("操作员");
        obj.add("产品编码");
        obj.add("源产品编码");
        obj.add("规格编码");
        obj.add("产品数量");
        obj.add("采购数量");
        obj.add("未采购数量");
        obj.add("采购单号");
        obj.add("采购签约日期");
        obj.add("中文描述");
        obj.add("英文描述");
        obj.add("采购交货日期");
        obj.add("采购反馈交期");
        obj.add("采购操作员");
        return obj;
    }

    private void excelTitleTaskInfoExport(JSONArray data,List<QueryTaskStatisticsTwoRes> list){
        for (QueryTaskStatisticsTwoRes vo:list){
            JSONArray infoList = new JSONArray();
            infoList.add(getNotNullOfStringInfo(vo.getStatusStr()));
            infoList.add(getNotNullOfStringInfo(vo.getContractNo()));
            infoList.add(getNotNullOfStringInfo(vo.getContractSignDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getSalesmanName()));
            infoList.add(getNotNullOfStringInfo(vo.getOperatorName()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSourceProductCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSpecCode()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProductNum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getPurchaseNum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUnPurchaseNum()));
            infoList.add(getNotNullOfStringInfo(vo.getPurchaseOrderNo()));
            infoList.add(getNotNullOfStringInfo(vo.getPurSignDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getChineseDesc()));
            infoList.add(getNotNullOfStringInfo(vo.getEnglishDesc()));
            infoList.add(getNotNullOfStringInfo(vo.getPurDelDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getPurFeeDelDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getPurOperatorName()));
            data.add(infoList);
        }
    }












    /**
     * 校验是否可以回退数据 1:采购调用 2:出运计划调用 0:未被调用
     *
     * @param id     备货id
     * @param billNo 备货单号
     * @return 是否可以回退数据: 1:采购调用  0:未被调用
     */
    public Integer checkDataIsRollBackByBillNo(Integer id, String billNo) {
        //通过外销合同号获取已做采购数量
        int count = exportContractProductService.getUsedPurchaseInfoByConcatNo(billNo);
        if (count > 0) {
            return 1;
        }
        return 0;
    }
}
